/*
 * padl_timer.h
 *
 *  Created on: 22/02/2010
 *      Author: gustavo
 */

#ifndef padl_TIMER_H_
#define padl_TIMER_H_


#include "target.h"


#define padl_timer_TIMER0              ((padl_timer_TimerType *) 0xE0004000)
#define padl_timer_TIMER1              ((padl_timer_TimerType *) 0xE0008000)
#define padl_timer_TIMER2              ((padl_timer_TimerType *) 0xE0070000)
#define padl_timer_TIMER3              ((padl_timer_TimerType *) 0xE0074000)

typedef struct
{
	REGISTER RW U32 IR;
	REGISTER RW U32 TCR;
	REGISTER RW U32 TC;
	REGISTER RW U32 PR;
	REGISTER RW U32 PC;
	REGISTER RW U32 MCR;
	REGISTER RW U32 MR0;
	REGISTER RW U32 MR1;
	REGISTER RW U32 MR2;
	REGISTER RW U32 MR3;
	REGISTER RW U32 CCR;
	REGISTER RO U32 CR0;
	REGISTER RO U32 CR1;
	REGISTER RO U32 CR2;
	REGISTER RO U32 CR3;
	REGISTER RW U32 EMR;
	U32 RESERVED1[12];
	union {
		REGISTER RW U32 CTCR;
		struct {
			REGISTER RW U8 operationMode : 2;
			REGISTER RW U8 countInputSel : 2;
		} CTCR_detailed;
	};
} padl_timer_TimerType;

#define padl_timer_CTCR_TIMER_MODE			0
#define padl_timer_CTCR_COUNTER_MODE_R		1
#define padl_timer_CTCR_COUNTER_MODE_F		2
#define padl_timer_CTCR_COUNTER_MODE_R_F		3

#define padl_timer_MR_MATCH_CHANNEL_0		0
#define padl_timer_MR_MATCH_CHANNEL_1		1
#define padl_timer_MR_MATCH_CHANNEL_2		2
#define padl_timer_MR_MATCH_CHANNEL_3		3


#define padl_timer_START_CONFIG(timer) \
	((padl_timer_TimerType *) timer)->TCR = 2;

#define padl_timer_FINISH_CONFIG(timer) \
	((padl_timer_TimerType *) timer)->TCR = 1;

#define padl_timer_TURN_ON(timer) \
	((padl_timer_TimerType *) timer)->TCR |= 1;

#define padl_timer_TURN_OFF(timer) \
	((padl_timer_TimerType *) timer)->TCR &= ~1;

#define padl_timer_OPERATION_MODE(timer, mode) \
	((padl_timer_TimerType *) timer)->CTCR_detailed.operationMode = mode;

#define padl_timer_SET_PRESCALER(timer, prescaler) \
	((padl_timer_TimerType *) timer)->PR = prescaler;

#define padl_timer_SET_MATCH_VALUE(timer, channel, value) \
	(*(&(((padl_timer_TimerType *) timer)->MR0) + channel) = value);

#define padl_timer_ENABLE_INTERRUPT_ON_MATCH(timer, channel) \
	((padl_timer_TimerType *) timer)->MCR |= (1 << (channel*3));

#define padl_timer_DISABLE_INTERRUPT_ON_MATCH(timer, channel) \
	((padl_timer_TimerType *) timer)->MCR &= ~(1 << (channel*3));

#define padl_timer_ENABLE_RESET_ON_MATCH(timer, channel) \
	((padl_timer_TimerType *) timer)->MCR |= (2 << (channel*3));

#define padl_timer_DISABLE_RESET_ON_MATCH(timer, channel) \
	((padl_timer_TimerType *) timer)->MCR &= ~(2 << (channel*3));

#define padl_timer_ENABLE_STOP_ON_MATCH(timer, channel) \
	((padl_timer_TimerType *) timer)->MCR |= (4 << (channel*3));

#define padl_timer_DISABLE_STOP_ON_MATCH(timer, channel) \
	((padl_timer_TimerType *) timer)->MCR &= ~(4 << (channel*3));

#define padl_timer_CLEAR_MATCH_INTERRUT(timer, channel) \
	(((padl_timer_TimerType *) timer)->IR = (1 << channel))


#endif /* padl_TIMER_H_ */
